'use client';

import type {
  IDifference,
  IPagination,
  IParentReply,
  IQueryParams,
  IUpdateParentReplyReviewStatusBody,
} from '@/interfaces';
import type { TBody, TCommentReviewState } from '@/types';
import {
  searchParentReply,
  serverQueryAllParentReplyByReplyId,
  updateParentReplyReviewStatus,
} from '@/services/api';
import {
  type ChangeEvent,
  type Dispatch,
  type FormEvent,
  type SetStateAction,
  useContext,
  useEffect,
  useRef,
  useState,
} from 'react';
import { useMutation, useQuery } from '@tanstack/react-query';
import classNames from 'classnames';
import Alert from '@/app/[locale]/alert/alert';
import AlertLoad from '@/app/[locale]/alert/load';
import useToast from '@/hooks/useToast';
import useContentLayer from '@/hooks/useContentLayer';
import { ReplyAdminContext } from '@/contexts/admin/forum/reply';
import {
  cleanFormData,
  formatDate,
  getDiffData,
  getFilterData,
  isEmpty,
} from '@/lib/tool';
import diff from 'microdiff';

export default function ParentReplyReplyAdminPage(this: any) {
  const { show } = useToast();
  const [searchName, setSearchName] = useState('');
  const [params, setParams] = useState<IQueryParams>({
    page: 0,
  });
  const [currentItemId, setCurrentItemId] = useState<number>();
  const context = useContext(ReplyAdminContext);
  const [replyItem, setReplyItem] = useState<IParentReply>();
  const [isOpenReplyContent, setIsOpenReplyContent] = useState(false);
  const [isOpenReplyReviewState, setIsOpenReplyReviewState] = useState(false);

  const serverQueryAllParentReplyByReplyIdQuery = useQuery(
    [
      '/forum',
      '/replies',
      '/server',
      context.replyItem?.id,
      '/parent',
      params,
      searchName,
    ],
    async (context) => {
      if (searchName) {
        return (await searchParentReply({
          query: {
            ...(context.queryKey[5] as any),
            name: context.queryKey[6],
          },
        })) as IPagination<IParentReply>;
      } else {
        return (await serverQueryAllParentReplyByReplyId({
          id: context.queryKey[3] + '',
          query: context.queryKey[5] as any,
        })) as IPagination<IParentReply>;
      }
    },
    {
      keepPreviousData: true,
    },
  );

  function onChangeSearch(e: ChangeEvent<HTMLInputElement>) {
    const value = e.target.value.trim();
    setSearchName(value.toLowerCase());
  }

  function onClickPrevious() {
    const data = serverQueryAllParentReplyByReplyIdQuery.data;
    if (!data) {
      show({
        type: 'DANGER',
        message: '数据不存在',
      });
      return;
    }

    const page = Math.max(0, data.pageable.page - 1);
    setParams({ ...params, page });
  }

  function onClickNext() {
    const data = serverQueryAllParentReplyByReplyIdQuery.data;
    if (!data) {
      show({
        type: 'DANGER',
        message: '数据不存在',
      });
      return;
    }

    const page = Math.min(data.pageable.pages, data.pageable.page + 1);
    setParams({ ...params, page });
  }

  function onClickRow(item: IParentReply) {
    setCurrentItemId(item.id);
    setReplyItem(item);

    if (typeof context.setParentReplyItem === 'function') {
      context.setParentReplyItem(item);
    }
  }

  function onClickDetails(item: IParentReply) {
    setReplyItem(item);
    setIsOpenReplyContent(true);
  }

  function onClickSquare(item: IParentReply) {
    setReplyItem(item);
    setIsOpenReplyReviewState(true);
  }

  if (serverQueryAllParentReplyByReplyIdQuery.data) {
    const data = serverQueryAllParentReplyByReplyIdQuery.data;

    return (
      <div className="row">
        <div className="col">
          <div className="card">
            <div className="card-header bg-transparent">
              <div className="row row-cols-auto justify-content-between g-2">
                <div className="col w-100">
                  <div className="input-group">
                    <span className="input-group-text">
                      <i className="bi bi-search"></i>
                    </span>
                    <input
                      onChange={onChangeSearch}
                      type="search"
                      className="form-control"
                      placeholder="搜索下级回复"
                    />
                  </div>
                </div>
              </div>
            </div>
            <div className="card-body">
              <div className="table-responsive">
                <table className="table table-hover align-middle">
                  <thead>
                    <tr className="text-nowrap">
                      <th scope="col" className="w-10">
                        Uid
                      </th>
                      <th scope="col" className="w-10">
                        内容
                      </th>
                    </tr>
                  </thead>
                  <tbody>
                    {data.content.map((item) => {
                      return (
                        <tr
                          key={item.id}
                          className={classNames('text-nowrap', {
                            'table-active': currentItemId === item.id,
                          })}
                        >
                          <td
                            onClick={onClickRow.bind(this, item)}
                            className="cursor-pointer"
                          >
                            <div>
                              {item.creatorAlias}&nbsp;({item.createdBy})
                            </div>
                            <div>
                              <time dateTime={item.createdOn}>
                                {formatDate(item.createdOn)}
                              </time>
                            </div>
                          </td>
                          <td className="text-truncate">
                            {!item.emptyChildReplyList && (
                              <div className="d-inline-block me-2">
                                <button
                                  onClick={onClickRow.bind(this, item)}
                                  className="btn btn-sm btn-light"
                                  type="button"
                                >
                                  <i className="bi bi-arrow-right-square"></i>
                                </button>
                              </div>
                            )}

                            <div className="d-inline-block me-2">
                              <button
                                onClick={onClickSquare.bind(this, item)}
                                className="btn btn-sm btn-light"
                                type="button"
                              >
                                {item.reviewState === 'APPROVED' && (
                                  <i
                                    title="审核通过"
                                    className="bi bi-check-square"
                                  ></i>
                                )}

                                {item.reviewState === 'DENIED' && (
                                  <i
                                    title="审核不通过"
                                    className="bi bi-x-lg"
                                  ></i>
                                )}

                                {item.reviewState === 'PENDING' && (
                                  <span>等待审核</span>
                                )}

                                {item.reviewState === 'CLOSE' && (
                                  <span>关闭审核</span>
                                )}
                              </button>
                            </div>

                            <div className="d-inline-block me-2">
                              <button
                                onClick={onClickDetails.bind(this, item)}
                                className="btn btn-sm btn-light"
                                type="button"
                              >
                                <i className="bi bi-info-square"></i>
                              </button>
                            </div>
                            <div className="d-inline-block">{item.content}</div>
                          </td>
                        </tr>
                      );
                    })}
                  </tbody>
                </table>
              </div>

              {data.content.length === 0 && <Alert message="暂无父回复" />}

              <div className="my-4">
                <nav aria-label="回复分页">
                  <ul className="pagination justify-content-end">
                    <li
                      className={classNames(
                        'page-item',
                        data.pageable.previous ? false : 'disabled',
                      )}
                    >
                      <a
                        onClick={onClickPrevious}
                        className="page-link cursor-pointer"
                      >
                        上一页
                      </a>
                    </li>
                    <li
                      className={classNames(
                        'page-item',
                        data.pageable.next ? false : 'disabled',
                      )}
                    >
                      <a
                        onClick={onClickNext}
                        className="page-link cursor-pointer"
                      >
                        下一页
                      </a>
                    </li>
                  </ul>
                </nav>
              </div>
            </div>
          </div>

          {replyItem && isOpenReplyContent && (
            <ParentReplyContentDetails
              item={replyItem}
              setIsOpenReplyContent={setIsOpenReplyContent}
            />
          )}

          {replyItem && isOpenReplyReviewState && (
            <ParentReplyReviewState
              item={replyItem}
              setIsOpenReplyReviewState={setIsOpenReplyReviewState}
            />
          )}
        </div>
      </div>
    );
  }

  if (serverQueryAllParentReplyByReplyIdQuery.error) {
    return (
      <Alert
        message={serverQueryAllParentReplyByReplyIdQuery.error}
        type="error"
      />
    );
  }

  return <AlertLoad />;
}

const ParentReplyContentDetails = ({
  item,
  setIsOpenReplyContent,
}: {
  item: IParentReply;
  setIsOpenReplyContent: Dispatch<SetStateAction<boolean>>;
}) => {
  const context = useContext(ReplyAdminContext);
  const viewModalRef = useRef<HTMLDivElement>(null);
  const metadata = context.metadata!;

  useContentLayer({
    dep: item.content,
    metadata,
  });

  useEffect(() => {
    onClickOpenModal();
  }, []);

  function onClickOpenModal() {
    getViewModal().show();
  }

  function onClickCloseModal() {
    getViewModal().hide();
    setIsOpenReplyContent(false);
  }

  function getViewModal() {
    const current = viewModalRef.current;
    if (!current) {
      throw '查看元素不存在';
    }

    return window.bootstrap.Modal.getOrCreateInstance(current);
  }

  return (
    <div ref={viewModalRef} className="modal fade" data-bs-backdrop="static">
      <div className="modal-dialog modal-dialog-centered modal-dialog-scrollable">
        <div className="modal-content">
          <div className="modal-header">
            <h5 className="modal-title">
              {`查看 ${item.creatorAlias} (${item.createdBy}) 回复内容`}
            </h5>
            <button
              onClick={onClickCloseModal}
              type="button"
              className="btn-close"
              aria-label="Close"
            ></button>
          </div>
          <div className="modal-body">
            <div
              className="content-layer clearfix content-layer-reply-parent text-break"
              dangerouslySetInnerHTML={{ __html: item.content }}
            ></div>
          </div>
        </div>
      </div>
    </div>
  );
};

const ParentReplyReviewState = ({
  item,
  setIsOpenReplyReviewState,
}: {
  item: IParentReply;
  setIsOpenReplyReviewState: Dispatch<SetStateAction<boolean>>;
}) => {
  const [form, setForm] = useState<{
    reviewState?: TCommentReviewState;
    reviewReason?: string;
  }>({
    reviewReason: '',
  });
  const { show } = useToast();
  const updateModalRef = useRef<HTMLDivElement>(null);
  const [differenceData, setDifferenceData] = useState<IDifference[]>([]);
  const [currentReviewState, setCurrentReviewState] = useState(
    item.reviewState,
  );

  const updateParentReplyReviewStatusMutation = useMutation(
    async (variables: TBody<IUpdateParentReplyReviewStatusBody>) => {
      await updateParentReplyReviewStatus(variables);
    },
  );

  useEffect(() => {
    onClickOpenModal();
  }, []);
  useEffect(() => {
    if (item) {
      setForm({
        reviewState: item.reviewState,
        reviewReason: item.reviewReason || '',
      });
    }
  }, [item]);
  useEffect(() => {
    if (item) {
      const differences = diff(
        {
          reviewState: item.reviewState,
          reviewReason: item.reviewReason || '',
        },
        {
          reviewState: form.reviewState,
          reviewReason: form.reviewReason,
        },
      );
      setDifferenceData(differences);
    }
  }, [form, item]);

  function onChange(e: ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) {
    const name = e.target.name;
    const value = e.target.value;

    if (name === 'reviewState') {
      setForm({ ...form, reviewState: value as TCommentReviewState });
      setCurrentReviewState(value as TCommentReviewState);
    } else {
      setForm({ ...form, [name]: value });
    }
  }

  async function onClickSave(e: FormEvent<HTMLFormElement>) {
    try {
      e.preventDefault();
      e.stopPropagation();

      const body = getFilterData(getDiffData(differenceData));
      if (isEmpty(body)) {
        show({
          type: 'SUCCESS',
          message: '保存完成',
        });
        return;
      }

      await updateParentReplyReviewStatusMutation.mutateAsync({
        id: item.id + '',
        data: body as any,
      });

      clearData();
      show({
        type: 'SUCCESS',
        message: '保存完成',
      });
    } catch (e) {
      updateParentReplyReviewStatusMutation.reset();
      show({
        type: 'DANGER',
        message: e,
      });
    }
  }

  function clearData() {
    setForm(cleanFormData(form));
    setDifferenceData([]);
  }

  function onClickOpenModal() {
    getUpdateModal().show();
  }

  function onClickCloseModal() {
    getUpdateModal().hide();
    setIsOpenReplyReviewState(false);
  }

  function getUpdateModal() {
    const current = updateModalRef.current;
    if (!current) {
      throw '查看元素不存在';
    }

    return window.bootstrap.Modal.getOrCreateInstance(current);
  }

  return (
    <div ref={updateModalRef} className="modal fade" data-bs-backdrop="static">
      <div className="modal-dialog modal-dialog-centered modal-dialog-scrollable">
        <div className="modal-content">
          <div className="modal-header">
            <h5 className="modal-title">
              {`修改 ${item.creatorAlias} (${item.createdBy}) 回复状态`}
            </h5>
            <button
              onClick={onClickCloseModal}
              type="button"
              className="btn-close"
              aria-label="Close"
            ></button>
          </div>
          <div className="modal-body">
            <form onSubmit={onClickSave} className="vstack gap-4">
              <div className="form-control user-select-none">
                <div className="form-check form-check-inline">
                  <input
                    onChange={onChange}
                    className="form-check-input"
                    type="radio"
                    name="reviewState"
                    value="APPROVED"
                    checked={currentReviewState === 'APPROVED'}
                    id="yw-comment-reviewState-radio-approved"
                  />
                  <label
                    htmlFor="yw-comment-reviewState-radio-approved"
                    className="form-check-label"
                  >
                    审核通过
                  </label>
                </div>
                <div className="form-check form-check-inline">
                  <input
                    onChange={onChange}
                    className="form-check-input"
                    type="radio"
                    name="reviewState"
                    value="DENIED"
                    checked={currentReviewState === 'DENIED'}
                    id="yw-comment-reviewState-radio-denied"
                  />
                  <label
                    htmlFor="yw-comment-reviewState-radio-denied"
                    className="form-check-label"
                  >
                    审核不通过
                  </label>
                </div>
                <div className="form-check form-check-inline">
                  <input
                    onChange={onChange}
                    className="form-check-input"
                    type="radio"
                    name="reviewState"
                    value="PENDING"
                    checked={currentReviewState === 'PENDING'}
                    id="yw-comment-reviewState-radio-pending"
                  />
                  <label
                    htmlFor="yw-comment-reviewState-radio-pending"
                    className="form-check-label"
                  >
                    等待审核
                  </label>
                </div>
                <div className="form-check form-check-inline">
                  <input
                    onChange={onChange}
                    className="form-check-input"
                    type="radio"
                    name="reviewState"
                    value="CLOSE"
                    checked={currentReviewState === 'CLOSE'}
                    id="yw-comment-reviewState-radio-close"
                  />
                  <label
                    htmlFor="yw-comment-reviewState-radio-close"
                    className="form-check-label"
                  >
                    关闭审核
                  </label>
                </div>
              </div>

              <div>
                <textarea
                  rows={1}
                  value={form.reviewReason}
                  name="reviewReason"
                  onChange={onChange}
                  className="form-control"
                  placeholder="请输入审核理由"
                />
              </div>

              <button
                type="submit"
                disabled={updateParentReplyReviewStatusMutation.isLoading}
                className="btn btn-success w-25 my-4"
              >
                {updateParentReplyReviewStatusMutation.isLoading && (
                  <span
                    className="spinner-border spinner-border-sm me-2"
                    role="status"
                    aria-hidden="true"
                  ></span>
                )}
                更新
              </button>
            </form>
          </div>
        </div>
      </div>
    </div>
  );
};
